
package com.wwy.monitor.service.impl;

import com.ali.com.google.common.base.Preconditions;
import com.wwy.monitor.common.MessageException;
import com.wwy.monitor.mapper.tddl.MonitorAppMapper;
import com.wwy.monitor.mapper.tddl.MonitorIpMapper;
import com.wwy.monitor.model.enumeration.DeleteEnum;
import com.wwy.monitor.model.enumeration.EnableStatusEnum;
import com.wwy.monitor.model.enumeration.MonitorEnvEnum;
import com.wwy.monitor.model.tddl.dto.MonitorAppDTO;
import com.wwy.monitor.model.tddl.dto.MonitorIpDTO;
import com.wwy.monitor.model.tddl.query.MonitorAppQuery;
import com.wwy.monitor.model.tddl.query.MonitorIpQuery;
import com.wwy.monitor.model.tddl.query.MonitorTaskQuery;
import com.wwy.monitor.model.tddl.vo.MonitorIpVO;
import com.wwy.monitor.model.vo.ServerInfo;
import com.wwy.monitor.service.MonitorIpService;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import com.alibaba.ais.skyline.client.bootstrap.Skyline;
import com.alibaba.ais.skyline.common.service.Result;
import com.alibaba.ais.skyline.domain.search.QueryRequest;
import com.alibaba.ais.skyline.domain.search.response.ItemQueryResponse;
import com.alibaba.druid.support.monitor.entity.MonitorApp;
import com.alibaba.fastjson.JSON;

/**
 * @author tianquan.ld
 * @version V1.0
 * <p>Description: çæ§ip service impl</p>
 * @date 2019-10-30 21:18
 */
@Service(value = "monitorIpService")
public class MonitorIpServiceImpl implements MonitorIpService {
    @Resource
    private MonitorIpMapper monitorIpMapper;
    @Autowired
    private MonitorAppMapper monitorAppMapper;
    @Value("${server.env}")
    private String env;

    @Override
    public boolean insert(MonitorIpDTO entity) {
        entity.setCreateTime(new Date());
        entity.setUpdateTime(new Date());
//        Integer appStatus = monitorIpMapper.selectAppStatusByIpId(entity.getId());
//        if (null == appStatus || EnableStatusEnum.DISABLE.getValue() == appStatus) {
//            throw new MessageException("åºç¨ä¸å¯ç¨ï¼");
//        }
        return monitorIpMapper.insert(entity) == 1;
    }

    @Override
    public boolean insertBatch(List<MonitorIpDTO> list) {
        return monitorIpMapper.batchInsert(list) == list.size();
    }

    @Override
    public boolean deleteByIds(String ids) {
        return monitorIpMapper.deleteByIds(getListIds(ids)) > 0;
    }

    private List<Integer> getListIds(String ids) {
        if (StringUtils.isBlank(ids)) {
            throw new MessageException("idä¸è½ä¸ºç©º!");
        }
        String[] strings = ids.split(",");
        List<Integer> list = Lists.newArrayList();
        try {
            for (String str : strings) {
                list.add(Integer.parseInt(str));
            }
            return list;
        } catch (Exception e) {
            throw new MessageException("非法id");
        }
    }

    @Override
    public boolean deleteById(Long id) {
        return monitorIpMapper.deleteById(id) == 1;
    }

    @Override
    public int deleteByAppId(Long appId) {
        return monitorIpMapper.deleteByAppId(appId);
    }

    @Override
    public boolean updateById(MonitorIpDTO entity) {
        entity.setUpdateTime(new Date());
        if (entity.getStatus() != null && EnableStatusEnum.ENABLE.getValue() == entity.getStatus()) {
            Integer appStatus = monitorIpMapper.selectAppStatusByIpId(entity.getId());
            if (null == appStatus || EnableStatusEnum.DISABLE.getValue() == appStatus) {
                throw new MessageException("åºç¨ä¸å¯ç¨ï¼");
            }
        }
        return monitorIpMapper.updateById(entity) == 1;
    }

    @Override
    public int offlineIpByAppId(Long appId) {
        return monitorIpMapper.offlineIpByAppId(appId);
    }

    @Override
    public List<MonitorIpDTO> getAllIpByAppId(Long appId, String ip) {
        return monitorIpMapper.getAllIpByAppId(appId, ip);
    }

    @Override
    public Integer selectAppStatusByIpId(Long id) {
        return monitorIpMapper.selectAppStatusByIpId(id);
    }

    @Override
    public List<MonitorIpDTO> selectByQuery(MonitorIpQuery query) {
        return monitorIpMapper.selectByQuery(query);
    }

    @Override
    public List<MonitorIpVO> queryMonitorIp(MonitorIpQuery query) {
        return monitorIpMapper.queryMonitorIp(query);
    }

    @Override
    public MonitorIpDTO selectById(Long id) {
        return monitorIpMapper.selectById(id);
    }

    @Override
    public Integer count(MonitorIpQuery query) {
        return monitorIpMapper.count(query);
    }

    @Override
    public List<ServerInfo> getServerIps(String appName) {
        int page = 1;
        int pageSize = 1000;
        List<ServerInfo> resultList = Lists.newArrayList();
//å¤æ­æ¯å¦æappName,æ²¡æåæ¥å¨é¨åºç¨
        MonitorAppQuery query = new MonitorAppQuery();
        query.setAppName(appName);
        List<MonitorAppDTO> appDTOS = monitorAppMapper.selectListByAppName(query);
        if (appDTOS != null && appDTOS.size() > 0) {
            for (MonitorAppDTO dto : appDTOS) {
                QueryRequest request = new QueryRequest();
                request.setFrom("server");
                request.setSelect("sn, ip, app.name , app_use_type");
                request.setCondition("app_use_type = 'PUBLISH' AND app_server_state = 'working_online' AND app.name = '" + dto.getAppName() + "'");
//ç¿»é¡µæ§å¶,ä»1å¼å§
                request.setPage(page);
//ä¸é¡µæå¤1000
                request.setNum(pageSize);
//hsfè°ç¨
                Result<ItemQueryResponse> result = Skyline.itemSearch().query(request);
                Preconditions.checkArgument(result.isSuccess(), "querySky error,request:%s,result:%s",
                        JSON.toJSONString(request), JSON.toJSONString(result));
                ItemQueryResponse response = result.getValue();
                if (response.getItemList() != null && response.getItemList().size() > 0) {
                    for (Map<String, Object> map : response.getItemList()) {
                        ServerInfo info = new ServerInfo();
                        info.setSn(MapUtils.getString(map, "sn"));
                        info.setIp(MapUtils.getString(map, "ip"));
                        info.setAppName(MapUtils.getString(map, "app.name"));
                        info.setAppId(dto.getId());
                        info.setAppUseType(MapUtils.getString(map, "app_use_type"));
                        resultList.add(info);
                    }
                }
            }
        }
        return resultList;
    }

    @Override
    public boolean syncServerIp(String appName) {
        List<ServerInfo> serverInfoList = getServerIps(appName);
        if (serverInfoList != null && serverInfoList.size() > 0) {
            Set<Long> appids = serverInfoList.stream().map(ServerInfo::getAppId).collect(Collectors.toSet());
            List<Long> appIds = Lists.newArrayList(appids);
//æ¥è¯¢ææå·²å­æºå¨ipä¿¡æ¯
            List<MonitorIpDTO> monitorIpDTOS = monitorIpMapper.selectByAppIds(appIds, null,
                    MonitorEnvEnum.parseStatus(env));
            Map<String, List<MonitorIpDTO>> ipMap = Maps.newHashMap();
            if (monitorIpDTOS != null && monitorIpDTOS.size() > 0) {
                ipMap = monitorIpDTOS.stream().collect(Collectors.groupingBy(MonitorIpDTO::getIp));
            }
//å¾ªç¯åºç¨ipï¼å¤çå·²å­ipçç¶æ
            List<MonitorIpDTO> saveList = Lists.newArrayList();
            for (ServerInfo serverInfo : serverInfoList) {
                MonitorIpDTO ipDTO = new MonitorIpDTO();
                ipDTO.setIp(serverInfo.getIp());
                ipDTO.setAppId(serverInfo.getAppId());
                ipDTO.setEnv(MonitorEnvEnum.parseStatus(env));
                ipDTO.setStatus(EnableStatusEnum.ENABLE.getValue());
                ipDTO.setIsDelete(DeleteEnum.NOT_DELETE.getValue());
                ipDTO.setCreateTime(new Date());
                ipDTO.setUpdateTime(new Date());
                ipDTO.setCreateUser("system");
                ipDTO.setCreateUser("system");
                ipDTO.setUpdateUser("system");
                if (ipMap.containsKey(serverInfo.getIp())) {
                    ipDTO.setStatus(ipMap.get(serverInfo.getIp()).get(0).getStatus());
                }
                saveList.add(ipDTO);
            }
            if (saveList.size() > 0) {
//åå é¤åå­å¨çip
                monitorIpMapper.deleteByAppIds(appIds);
//åä¿å­æ°çip
                return monitorIpMapper.batchInsert(saveList) > 0;
            }
        }
        return false;
    }
}